﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Maps.Toolkit;
using Microsoft.Phone.Maps.Controls;
using System.Device.Location;
using System.Windows.Media;
using System.IO.IsolatedStorage;
using Windows.Devices.Geolocation;
using System.Collections;
using TanZim_vai_MVVM_MAP.ViewModel;
using System.Collections.ObjectModel;
using Microsoft.Phone.Maps.Services;
using System.Diagnostics;
 


namespace TanZim_vai_MVVM_MAP
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainViewModel _ViewModel = new MainViewModel();
        public GeoCoordinate myGeoCoordinate { get; set; }
 
       
        Pushpin myPosition;
        Placemarks temp;
        GeoCoordinate myPositionTemp;
        MapRoute calculatedMapRoute;





        private GeoPosition<GeoCoordinate> CurrentPosition { get; set; }
        public MainPage()
        {
            InitializeComponent();
            _autoBankCompleteBox.ItemsSource = this._ViewModel.Placemarks.Select(x => x.shortname).Distinct();
            _autoAreaCompleteBox.ItemsSource = this._ViewModel.Placemarks.Select(x => x.area).Distinct();
            _autoNearCompleteBox.ItemsSource = this._ViewModel.Placemarks.Select(x => x.shortname).Distinct();
            
        }
 
       

     
        
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains("LocationConsent"))
            {                
                return;
            }
            else
            {
                MessageBoxResult result =
                    MessageBox.Show("This app accesses your phone's location. Is that ok?", "Location", MessageBoxButton.OKCancel);

                if (result == MessageBoxResult.OK)
                {
                    IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = true;
                }
                else
                {
                    IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = false;
                }

                //IsolatedStorageSettings.ApplicationSettings.Save();
            }
        }
       
        private void setMyposition()
        {
            MapLayer layer = new MapLayer();
            MapOverlay overlayer = new MapOverlay();
            overlayer.GeoCoordinate = myPositionTemp;
            myPosition = new Pushpin();
            maps.SetView(myPositionTemp, 16);
            myPosition.Content = "Your Current Position";
            myPosition.Foreground = new SolidColorBrush(Colors.Red);
            overlayer.Content = myPosition;

            layer.Add(overlayer);
            maps.Focus();

            maps.Layers.Add(layer);
        }      
        private void _search_Click(object sender, RoutedEventArgs e)
        {
            maps.Layers.Clear();
            _radiusSearch.Visibility = Visibility.Collapsed;
            if (myPositionTemp!=null)
            {
                setMyposition();
            }
            
            if (calculatedMapRoute!=null)
            {
                maps.RemoveRoute(calculatedMapRoute);
            }
           
            
            var area = _autoAreaCompleteBox.SelectedItem;
            var bank = _autoBankCompleteBox.SelectedItem;
            var query = _ViewModel.Placemarks.Select(x => x).Where(x => x.area.Equals(area) && x.shortname.Equals(bank));

            if (area != null && bank != null)
            {
                query = _ViewModel.Placemarks.Select(x => x).Where(x => x.area.Equals(area) && x.shortname.Equals(bank));    
            }
            else if (area == null && bank != null)
            {
                query = _ViewModel.Placemarks.Select(x => x).Where(x => x.shortname.Equals(bank));
            }
            else if (area != null && bank == null)
            {
                query = _ViewModel.Placemarks.Select(x => x).Where(x => x.area.Equals(area));
            }
            else
            {
                MessageBox.Show("No Item is Selected");
            }

            temp = new Placemarks();
            temp.Clear();

            MapLayer layer = new MapLayer();
           
            foreach (var item in query)
            {
                temp.Add(item);
                Pushpin pushPin = new Pushpin();
                pushPin.Background = new SolidColorBrush(Colors.Red);
                pushPin.Opacity = 0.6;
                MapOverlay overlayer = new MapOverlay();
                overlayer.GeoCoordinate = new GeoCoordinate(item.GeoCoordinate.Latitude, item.GeoCoordinate.Longitude);
                pushPin.GeoCoordinate = item.GeoCoordinate;
                pushPin.Content = item.shortname;
                pushPin.Tap += pushPin_Tap;
                
                overlayer.Content = pushPin ;
                layer.Add(overlayer);
                maps.Focus();                
            }
            maps.Layers.Add(layer);
            if (!maps.Layers.Equals(null)&&temp.Count!=0)
            {
                if (myPositionTemp!=null)
                {                    
                    maps.SetView(new GeoCoordinate(nearest().Latitude, nearest().Longitude), 16);
                }
                else
                    maps.SetView(new GeoCoordinate(temp[temp.Count - 1].GeoCoordinate.Latitude, temp[temp.Count - 1].GeoCoordinate.Longitude), 16);
            }



            
            _autoComplete.Visibility = Visibility.Collapsed;
        }         
        void pushPin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            Pushpin pushpin = sender as Pushpin;

            string foo = pushpin.GeoCoordinate.ToString();
            string bar = "";
            foreach (var item in temp)
            {
                bar = item.GeoCoordinate.Latitude.ToString() + ", " + item.GeoCoordinate.Longitude.ToString();
                if (foo == bar)
                {
                    MessageBox.Show(PushPin_string(item));
                    break;
                }
            }
        }
        private string PushPin_string(AtmBooth ob)
        {
            string messag = "\nName : \n" + ob.name + "\n\nAddress : \n" + ob.formatted_address + "\n\nDistrict : \n" + ob.district;
            if (ob.formatted_phone_number!=null)
            {
                messag += "\n\nPhone Number : \n" + ob.formatted_phone_number;
            }
            if (ob.international_phone_number!=null)
            {
                messag += "\n\nInternational Phone Number : \n" + ob.international_phone_number;
            }
            if (ob.website!=null)
            {
                messag += "\n\nWebsite : \n" + ob.website;
            }
            return messag;
        }
       
        private async void ApplicationBarIconButton_Click(object sender, EventArgs e)
        {
            if (calculatedMapRoute != null)
            {
                maps.RemoveRoute(calculatedMapRoute);
            }
           
            if ((bool)IsolatedStorageSettings.ApplicationSettings["LocationConsent"] != true)
            {         
                return;
            }

            Geolocator geolocator = new Geolocator();
            geolocator.DesiredAccuracyInMeters = 50;

            try
            {
                 
                Geoposition geoposition = await geolocator.GetGeopositionAsync(
                    maximumAge: TimeSpan.FromMinutes(5),
                    timeout: TimeSpan.FromSeconds(30)
                    );               
                myPositionTemp = new GeoCoordinate(geoposition.Coordinate.Latitude, geoposition.Coordinate.Longitude);   
                //myPositionTemp = new GeoCoordinate(23.884906, 90.400054);
                setMyposition();
            }
            catch (Exception ex)
            {
                if ((uint)ex.HResult == 0x80004004)
                {
                    MessageBox.Show("location  is disabled in phone settings.");
                }
                else
                {
                    MessageBox.Show("GPS Can not found, please go outside or near window or Balcony");
                }
            }
        } 
        private void ApplicationBarIconButton2_Click(object sender, EventArgs e)
        {
            _autoComplete.Visibility = Visibility.Visible;
            _radiusSearch.Visibility = Visibility.Collapsed;
            if (calculatedMapRoute != null)
            {
                maps.RemoveRoute(calculatedMapRoute);
            }
        }
        private void ApplicationBarIconButton4_Click(object sender, EventArgs e)
        {
            if (temp == null)
            {
                MessageBox.Show("First select ATM Booth");
            }
            else if (myPositionTemp == null)
            {
                MessageBox.Show("Kindly Detect Your Location first");            
            }
            else
            {
                if (calculatedMapRoute != null)
                {
                    maps.RemoveRoute(calculatedMapRoute);
                }
                MessageBoxResult result = MessageBox.Show("We are going to draw a route to Your nearest ATM booth / Bank, al-right ??", "Confirm", MessageBoxButton.OKCancel);

                if (result == MessageBoxResult.OK)
                {
                    RouteQuery routeQuery = new RouteQuery();
                    routeQuery.QueryCompleted += routeQuery_QueryCompleted;


                    if (!routeQuery.IsBusy)
                    {
                        List<GeoCoordinate> routeCoordinates = new List<GeoCoordinate>();
                        routeCoordinates.Add(new GeoCoordinate(myPositionTemp.Latitude, myPositionTemp.Longitude)); //Eiffel Tower coordinates
                        routeCoordinates.Add(nearest());

                        routeQuery.Waypoints = routeCoordinates;
                        routeQuery.QueryAsync();

                        maps.Center = new GeoCoordinate(myPositionTemp.Latitude, myPositionTemp.Longitude); //Center map on first coordinates
                    }
                }
                else
                {
                    // user clicked no
                }
            }
        }
        private void ApplicationBarIconButton5_Click(object sender, EventArgs e)
        {
            _radiusSearch.Visibility = Visibility.Visible;
            _autoComplete.Visibility = Visibility.Collapsed;
            if (calculatedMapRoute != null)
            {
                maps.RemoveRoute(calculatedMapRoute);
            }
        }
        private GeoCoordinate nearest()
        {
            if (temp == null)
            {
                MessageBox.Show("Kindly select some Bank First");
            }
            List<Nearest> coOrdinateList = new List<Nearest>();
            List<Nearest> coOrdinateList2 = new List<Nearest>();
            if (myPositionTemp != null)
            {
                foreach (var item in temp)
                {
                    GeoCoordinate bar = new GeoCoordinate(myPositionTemp.Latitude, myPositionTemp.Longitude);
                    double distance = item.GeoCoordinate.GetDistanceTo(bar);
                    Nearest foo = new Nearest();
                    foo.GeoCordinate = item.GeoCoordinate;
                    foo.distance = distance;
                    coOrdinateList.Add(foo);
                }
                var query = coOrdinateList.OrderBy(x => x.distance);
                foreach (var item in query)
                {
                    coOrdinateList2.Add(item);
                }
                return coOrdinateList2[0].GeoCordinate;
            }
            else 
                return temp[0].GeoCoordinate;
           
        }        
        private void routeQuery_QueryCompleted(object sender, QueryCompletedEventArgs<Route> e)
        {
            Route theRoute = e.Result;
            calculatedMapRoute = new MapRoute(theRoute);
            maps.AddRoute(calculatedMapRoute);
           
        }
        private void _radiusLoad_Click(object sender, RoutedEventArgs e)
        {
            if (calculatedMapRoute != null)
            {
                maps.RemoveRoute(calculatedMapRoute);
            }
            _autoComplete.Visibility = Visibility.Collapsed;                    
            double distancelIMIT = 1000;
            var value = _radius.Text;
            if (value.Length!=0 )
            {
                distancelIMIT = Convert.ToDouble(_radius.Text);
                
            }
            if (myPositionTemp == null)
            {
                MessageBox.Show("Kindly Detect Your Location first");
            }
            else
            {
                List<Nearest> coOrdinateList = new List<Nearest>();
                List<Nearest> coOrdinateList2 = new List<Nearest>();
                int i = 0;
                maps.Layers.Clear();
                if (temp==null)
                {                    
                    temp = new Placemarks();
                    
                }
                else
                    temp.Clear();
                setMyposition();
                MapLayer layer = new MapLayer();
                var bank = _autoNearCompleteBox.SelectedItem;
                var query = _ViewModel.Placemarks.Select(x=>x);
                if (bank!= null)
                {                    
                    query = _ViewModel.Placemarks.Select(x => x).Where(x => x.shortname.Equals(bank));
                }
                foreach (var item in query)
                {
                    GeoCoordinate bar = new GeoCoordinate(myPositionTemp.Latitude, myPositionTemp.Longitude);
                    double distance = item.GeoCoordinate.GetDistanceTo(bar);
                    Nearest foo = new Nearest();
                    foo.GeoCordinate = item.GeoCoordinate;
                    foo.distance = distance;
                    
                   
                    if (distancelIMIT>=foo.distance)
                    {
                        i++;
                        temp.Add(item);
                        Pushpin rediusPushpin = new Pushpin();
                        MapOverlay overlayer = new MapOverlay();
                        overlayer.GeoCoordinate = foo.GeoCordinate;
                        rediusPushpin.Tap += pushPin_Tap;
                        rediusPushpin.Background = new SolidColorBrush(Colors.Red);
                        rediusPushpin.Opacity = 0.6;
                        rediusPushpin.GeoCoordinate = foo.GeoCordinate;
                        maps.SetView(myPositionTemp, 16);
                        rediusPushpin.Content = item.shortname;
                        //rediusPushpin.Foreground = new SolidColorBrush(Colors.Red);
                        overlayer.Content = rediusPushpin;

                        layer.Add(overlayer);
                        maps.Focus();
                    }                                       
                }
                maps.Layers.Add(layer);
            }
            _radiusSearch.Visibility = Visibility.Collapsed;   
        }

        private void maps_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            _autoComplete.Visibility = Visibility.Collapsed;
            _radiusSearch.Visibility = Visibility.Collapsed;
            if (calculatedMapRoute != null)
            {
                maps.RemoveRoute(calculatedMapRoute);
            }
        }
         

        private void PitchValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (PitchSlider == null)
                return;

            maps.Pitch = PitchSlider.Value;
        }

        private void HeadingValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (HeadingSlider == null)
            {
                return;
            }
            maps.Heading = HeadingSlider.Value;
        }

        private void OnAdReceived(object sender, GoogleAds.AdEventArgs e)
        {
            Debug.WriteLine("Received ad successfully");
        }

        private void OnFailedToReceiveAd(object sender, GoogleAds.AdErrorEventArgs e)
        {
            Debug.WriteLine("Failed to receive ad with error " + e.ErrorCode);
        }
          
    }
}